#ifndef JsObjectH
#define JsObjectH

#include"JsType.h"

struct JsEngine;
struct JsValue;
struct JsObject;

//JsObject.defaultValue.hit or ToObject.hit
#define JS_OBJECT_HIT_TYPE_STRING 	0
#define JS_OBJECT_HIT_TYPE_NUMBER 	1

//JsObject.flag
//!ATTR_READONLY !ATTR_DONTENUM !ATTR_DONTDELETE
#define JS_OBJECT_ATTR_DEFAULT 	    0x0
#define JS_OBJECT_ATTR_READONLY 	0x1
#define JS_OBJECT_ATTR_DONTENUM 	0x2
#define JS_OBJECT_ATTR_DONTDELETE 	0x4
#define JS_OBJECT_ATTR_STRICT		0x7

/*
	对象中的属性都为只读属性, 当初始化完成后, 就不能再进行修改了
	且其中任何属性都要为非NULL, 如果对象无该内置属性,则使用Dark*函数
	设置
*/
struct JsObject{
	/*通用属性*/
	struct JsObject* 		Prototype; 		
	const char *			Class;		
	JsObjectGetFn			Get;
	JsObjectPutFn			Put;
	JsObjectBooleanFn		CanPut;
	JsObjectBooleanFn		HasProperty;
	JsObjectBooleanFn		Delete;
	JsObjectDefaultValueFn  DefaultValue;
	/*额外的通用属性*/
	JsObjectBooleanFn		HasOwnProperty;
	JsObjectNextValueFn     NextValue;
	
	/*函数特有函数*/
	JsObjectCallFn			Construct;
	JsObjectCallFn			Call;
	JsObjectHasInstanceFn	HasInstance;
	JsList 					Scope;
	
	/*Internal state information associated with this object[[Value]]*/
	void* 					Value;
	/*synchronized 锁*/
	JsLock 					syncLock;
	
	/*Object 特化属性保存点*/
	void* 					self;
};

/****************************************************************************
									通用API
*****************************************************************************/
//如果Vm没有Object或者Function, prototype 配置为NULL
struct JsObject* JsCreateStandardObject();

//如果Scope = NULL, 则使用Global代替
//如果inst = TRUE, 则使用标准HasInstance, 且需要对象中属性中
//添加prototype属性(和Constructor属性配合使用)
struct JsObject* JsCreateFunctionObject(JsList scope, int inst);

//标准函数对象, 和JsCreateStandardFunction 联用,通常该API不被使用
struct JsObject* JsCreateStandardFunctionObject(JsList scope);



/*非标准内置函数*/
void JsDarkGet(struct JsObject *obj, char *prop,int* flag, struct JsValue *res);
void JsDarkPut(struct JsObject *obj,char *prop, struct JsValue *value, int flags);
void JsDarkBoolean(struct JsObject *obj,char *prop,struct JsValue* res);
void JsDarkHasInstance(struct JsObject *obj, struct JsValue *instance, struct JsValue* res);
void JsDarkCall(struct JsObject *obj, struct JsObject *thisobj,
			int argc, struct JsValue **argv, struct JsValue *res);
void JsDarkDefaultValueFn(struct JsObject *obj,int type, struct JsValue *res);
struct JsObject* JsDarkNextValueFn(struct JsObject* obj, JsIter* iter,int initialized,struct JsValue* res);


#endif